package question11_15;

/**
 * @description:
 * 把一个数组最开始的若干个元素搬到数组的末尾，我们称之为数组的旋转。
 * 输入一个非递减排序的数组的一个旋转，输出旋转数组的最小元素。
 * NOTE：给出的所有元素都大于0，若数组大小为0，请返回0。
 * 输入：[3,4,5,1,2]
 * 返回：1
 * @author: jhy
 * @time: 2021/5/20 12:53
 */
//旋转数组中最小的数据
public class Question11 {

    public static void main(String[] args) {
        int[] ints = {3,4,5,1,2};
        Question11 question11 = new Question11();
        int i = question11.minNumberInRotateArray2(ints);
        System.out.println(i);
    }


    //方法1：暴力循环
    public int minNumberInRotateArray(int[] array) {
        if (array == null || array.length == 0) {
            return 0;
        }
        int min = Integer.MAX_VALUE;
        for (int i = 0; i < array.length; i++) {
            if (min > array[i]) {
                min = array[i];
            }
        }
        return min;
    }


    //方法2：二分查找
    //对反转数组进行二分，分为两部分，肯定有一部分数组是有序的，最小值在不是有序那一部分
    //对不是有序的部分在进行二分
    public int minNumberInRotateArray2(int[] array) {
        if (array == null || array.length == 0) {
            return 0;
        }

        int i = 0;
        int j = array.length - 1;
        //第一种特殊情况：未旋转
        if(array[i] < array[j]){
            return array[i];
        }

        //第二种特殊情况array[i] = array[j] = array[mid] eg:{1,0,1,1,1}，只能顺序查找
        if(array[i] == array[(i+j)/2]&& array[i] == array[j]){
            int mix = Integer.MAX_VALUE;
            for(int k = 0;k < array.length;k++){
                if(mix >= array[k]){
                    mix = array[k];
                }
            }
            return mix;
        }

        //最一般的情况，进行二分，最终i指向前面有序数组的末尾，j指向后面有序数组的开头
        while (i <= j) {
            int mid = (i + j) / 2;
            if (array[i] < array[mid]) { //左半部分有序
                i = mid;
            } else if (array[mid] < array[j]) {  //右半部分有序
                j = mid;
            }else {
                break;
            }
        }
        return array[j];

    }
}

